<!DOCTYPE html>
<html lang="en">

<head>

<!-- AdThrive Head Tag Manual -->
<script data-no-optimize="1" data-cfasync="false">
(function(w, d) {
	w.adthrive = w.adthrive || {};
	w.adthrive.cmd = w.
	adthrive.cmd || [];
	w.adthrive.plugin = 'adthrive-ads-manual';
	w.adthrive.host = 'ads.adthrive.com';var s = d.createElement('script');
	s.async = true;
	s.referrerpolicy='no-referrer-when-downgrade';
	s.src = 'https://' + w.adthrive.host + '/sites/643436a4e6d20859e40a446b/ads.min.js?referrer=' + w.encodeURIComponent(w.location.href) + '&cb=' + (Math.floor(Math.random() * 100) + 1);
	var n = d.getElementsByTagName('script')[0];
	n.parentNode.insertBefore(s, n);
})(window, document);
</script>
<!-- End of AdThrive Head Tag -->





  <!-- Global site tag (gtag.js) - Google Analytics -->



  <script async src="https://www.googletagmanager.com/gtag/js?id=UA-79254642-6"></script>

  <script>
    window.dataLayer = window.dataLayer || [];
    function gtag(){dataLayer.push(arguments);}
    gtag('js', new Date());

    gtag('config', 'UA-79254642-6');
  </script>

  <meta charset="utf-8">
  <title>Vertical arc diagram in d3.js</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="Using d3.js to create a vertical arc diagram: explanation and reproducible code (d3.js v4 and v6)">
  <meta name="keywords" content="Data, Dataviz, Datavisualization, Javascript, JS, d3.js, boxplot">
  <meta name="author" content="Yan Holtz">
  <link rel="icon" href="../img/logo/D3_single_small.png">

  <meta property="og:title" content="Vertical arc diagram in d3.js">
  <meta property="og:image" content="https://www.d3-graph-gallery.com/img/logo/D3_full_medium.png">
  <meta property="og:description" content="Using d3.js to create a vertical arc diagram: explanation and reproducible code (d3.js v4 and v6)">

  <!-- Bootstrap core CSS -->
  <link href="../vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">

  <!-- Custom fonts for this template -->
  <link href="../vendor/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">

  <!-- Custom styles for this template -->
  <link href="../css/agency.css" rel="stylesheet">

  <!-- PRISM -->
  <script src="../LIB/prism.js"></script>
  <link href="../LIB/prism.css" rel="stylesheet" />

  <!-- JQUERY -->
  <script src="../vendor/jquery/jquery.min.js"></script>

  <!-- HTML TO CANVAS -->
  <script src="../js/html2canvas.js"></script>

  <!-- Function to parse html and js code chunks made by Yan Holtz -->
  <script src="../js/myParser.js"></script>

</head>






<body id="page-top">


<!-- THIS ALLOWS TO INSERT THE MENU THAT IS STORED IN A MENU.HTML FILE-->
<nav class="navbar navbar-expand-lg fixed-top" id="mainNav"></nav>
<script>
$(function(){
  $("#mainNav").load("../html_chunk/menu.html");
});
</script>

<!-- THIS ALLOWS TO INSERT THE MODAL OF THE MENU THAT IS STORED IN A MENU_MODAL.HTML FILE-->
<div id="modal_menu_insertion"> </div>
<script>
$(function(){
  $("#modal_menu_insertion").load("../html_chunk/menu_modal.html");
});
</script>


<!-- Header -->
<header class="masthead">
  <div class="textlanding">
      <h1>Vertical arc diagram in d3.js</h1>
      <hr class="short_hr">
      <br>
      <ul class="list-inline social-buttons">
        <li class="list-inline-item">
          <a href="https://twitter.com/R_Graph_Gallery">
            <i class="fa fa-twitter"></i>
          </a>
        </li>
        <li class="list-inline-item social-buttons">
          <a href="https://github.com/holtzy">
            <i class="fa fa-github" style="color: white"></i>
          </a>
        </li>
        <li class="list-inline-item social-buttons">
          <a href="https://www.linkedin.com/in/yan-holtz-2477534a/">
            <i class="fa fa-linkedin"></i>
          </a>
        </li>
        <li class="list-inline-item social-buttons">
          <a href="https://www.yan-holtz.com">
            <i class="fa fa-home"></i>
          </a>
        </li>
      </ul>
      <br><br>
      <p style="max-width: 700px; margin: auto">This post describes how to build a vertical <a href="../arc.html">arc diagram</a> with d3.js. It represent a very basic network composed of 10 nodes. You can see many other examples in the <a href="../arc.html">arc diagram section</a> of the gallery. Learn more about the theory of arc diagrams in <a href="https://www.data-to-viz.com/graph/arc.html">data-to-viz.com</a>.      <p style="max-width: 700px; margin: auto">This post describes how to build a vertical <a href="../arc.html">arc diagram</a> with d3.js. It represent a very basic network composed of 10 nodes. You can see many other examples in the <a href="../arc.html">arc diagram section</a> of the gallery. Learn more about the theory of arc diagrams in <a href="https://www.data-to-viz.com/graph/arc.html">data-to-viz.com</a>. This example works with d3.js <code>v4</code> and <code>v6</code></p>
    </p>
      <br>
      <a class="btn btn-secondary btn-md text-uppercase" href="../arc.html">Arc diagram section</a>
      <button class="btn btn-secondary btn-md text-uppercase" onclick="myCodeDownload('chart_example_from_d3-graph-gallery.html', 'code-html-v4', 'code-js-v4')">Download code</button>
  </div>
</header>



















<section class="bg" style="padding-top: 20px; padding-bottom: 20px"><div class="container" >
  <div class="row">

<!-- ==================== GRAPH SECTION = WHERE THE GRAPH APPEARS ==================== -->

  <div class="col-lg-5 .align-middle">
    <div style="position: -webkit-sticky; position: sticky; top: 120px">
      <div class="bg-light" id="result" ></div>
      <br>
      <div>
        <h5>Steps:</h5>
        <ul>
          <br>
          <li>Data input format is <code>Json</code>. <a href="network_data_format.html">This document</a> explains how to get this format from a classic table.</li>
          <br>
          <li>Plotting the <u>nodes</u> is pretty straightforward: a <a href="custom_axis.html">scalePoint()</a> is set to distribute them uniformly along the Y axis. They are then added using a classing <code>append("circle")</code> approach.</li>
          <br>
          <li>Drawing links is a bit tricky. Code is highly commented and should allow to understand the basic process.</li>
          <br>
          <li>See also the <a href="arc_basic.html">horizontal version</a>.</li>
        </ul>
      </div>
    </div>
  </div>

<!-- ================================================================================= -->




<!-- ==================== CODE SECTION = WHERE THE CODE APPEARS ==================== -->
<div class="col-lg-7 text-center .align-middle">

  <div class="v4-v6-toggle">
    <button id="button-show-v4" onclick="showCodeVersion('v4')" type="button" class="btn  btn-secondary btn-sm active">d3 v4</button>
    <span> | </span>
    <button id="button-show-v6" onclick="showCodeVersion('v6')" type="button" class="btn  btn-secondary btn-sm">d3 v6</button>
  </div>

<!-- ========= show html code ============== -->
<aside style="position: -webkit-sticky; position: sticky; top: 120px">&larr; Edit me! </aside>
<pre class="language-html d-none d3v4-chunk"><code id="code-html-v4" contenteditable="true"><xmp><!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
</xmp></code></pre>

<pre class="language-html d-none d3v6-chunk"><code id="code-html-v6" contenteditable="true"><xmp><!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v6.js"></script>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>
</xmp></code></pre>
<!-- ==================================== -->


<!-- ========= show JS code V4 ==============  -->
<pre class="language-js d-none d3v4-chunk"><code id="code-js-v4" contenteditable="true"><xmp><script>

// set the dimensions and margins of the graph
var margin = {top: 20, right: 30, bottom: 20, left: 30},
  width = 450 - margin.left - margin.right,
  height = 300 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
  .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")");

// Read dummy data
d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_network.json", function( data) {

  // List of node names
  var allNodes = data.nodes.map(function(d){return d.name})

  // A linear scale to position the nodes on the X axis
  var y = d3.scalePoint()
    .range([0, height])
    .domain(allNodes)

  // Add the circle for the nodes
  svg
    .selectAll("mynodes")
    .data(data.nodes)
    .enter()
    .append("circle")
      .attr("cx", 50)
      .attr("cy", function(d){ return(y(d.name))})
      .attr("r", 8)
      .style("fill", "#69b3a2")

  // And give them a label
  svg
    .selectAll("mylabels")
    .data(data.nodes)
    .enter()
    .append("text")
      .attr("x", 20)
      .attr("y", function(d){ return(y(d.name))})
      .text(function(d){ return(d.name)})
      .style("text-anchor", "middle")
      .style("alignment-baseline", "middle")

  // Add links between nodes. Here is the tricky part.
  // In my input data, links are provided between nodes -id-, NOT between node names.
  // So I have to do a link between this id and the name
  var idToNode = {};
  data.nodes.forEach(function (n) {
    idToNode[n.id] = n;
  });
  // Cool, now if I do idToNode["2"].name I've got the name of the node with id 2

  // Add the links
  svg
    .selectAll('mylinks')
    .data(data.links)
    .enter()
    .append('path')
    .attr('d', function (d) {
      start = y(idToNode[d.source].name)    // X position of start node on the X axis
      end = y(idToNode[d.target].name)      // X position of end node
      return ['M', 50, start,    // the arc starts at the coordinate x=start, y=height-30 (where the starting node is)
        'A',                            // This means we're gonna build an elliptical arc
        (start - end)/2*4, ',',    // Next 2 lines are the coordinates of the inflexion point. Height of this point is proportional with start - end distance
        (start - end)/2, 0, 0, ',',
        start < end ? 1 : 0, 50, ',', end] // We always want the arc on top. So if end is before start, putting 0 here turn the arc upside down.
        .join(' ');
    })
    .style("fill", "none")
    .attr("stroke", "black")

})

</script></xmp></code></pre>
<!-- ==================================== -->

<!-- ========= show JS code v6 ==============  -->
<pre class="language-js d-none d3v6-chunk"><code id="code-js-v6" contenteditable="true"><xmp><script>

// set the dimensions and margins of the graph
const margin = {top: 20, right: 30, bottom: 20, left: 30},
      width = 450 - margin.left - margin.right,
      height = 300 - margin.top - margin.bottom;

// append the svg object to the body of the page
const svg = d3.select("#my_dataviz")
              .append("svg")
              .attr("width", width + margin.left + margin.right)
              .attr("height", height + margin.top + margin.bottom)
              .append("g")
              .attr("transform",`translate(${margin.left},${margin.top})`);

// Read dummy data
d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_network.json").then(function(data) {

  // List of node names
  const allNodes = data.nodes.map(d=>d.name)

  // A linear scale to position the nodes on the X axis
  const y = d3.scalePoint()
            .range([0, height])
            .domain(allNodes)

  // Add the circle for the nodes
  svg
    .selectAll("mynodes")
    .data(data.nodes)
    .join("circle")
      .attr("cx", 50)
      .attr("cy", d=>y(d.name))
      .attr("r", 8)
      .style("fill", "#69b3a2")

  // And give them a label
  svg
    .selectAll("mylabels")
    .data(data.nodes)
    .join("text")
    .attr("x", 20)
    .attr("y", d=>y(d.name))
    .text(d=>d.name)
    .style("text-anchor", "middle")
    .style("alignment-baseline", "middle")

  // Add links between nodes. Here is the tricky part.
  // In my input data, links are provided between nodes -id-, NOT between node names.
  // So I have to do a link between this id and the name
  const idToNode = {};
  data.nodes.forEach(function (n) {
    idToNode[n.id] = n;
  });
  // Cool, now if I do idToNode["2"].name I've got the name of the node with id 2
  // Add the links
  svg
    .selectAll('mylinks')
    .data(data.links)
    .join('path')
    .attr('d', d=> {
      start = y(idToNode[d.source].name)    // X position of start node on the X axis
      end = y(idToNode[d.target].name)      // X position of end node
      return ['M', 50, start,    // the arc starts at the coordinate x=start, y=height-30 (where the starting node is)
        'A',                            // This means we're gonna build an elliptical arc
        (start - end)/2*4, ',',    // Next 2 lines are the coordinates of the inflexion point. Height of this point is proportional with start - end distance
        (start - end)/2, 0, 0, ',',
        start < end ? 1 : 0, 50, ',', end] // We always want the arc on top. So if end is before start, putting 0 here turn the arc upside down.
        .join(' ');
    })
    .style("fill", "none")
    .attr("stroke", "black")

})

</script></xmp></code></pre>
<!-- ==================================== -->


</div>


  </div>
</div>
</section>
<br>


<!-- ============================ -->








<!-- ============================ RELATED BLOCKS ============================ -->

<section class="bg-light" style="padding-top: 70px; padding-bottom: 70px">
  <div class="container">
    <div class="row">
      <div class="col-lg-5 text-center align-self-center">
        <h3 class="text-uppercase">Related blocks  &rarr;</h3>
      </div>
      <div class="col-lg-5">
        <ul>
          <li><i>Arc diagram section - </i> by <a href="../arc.html">the d3 graph gallery</a></li>
          <br>
          <li><i>Arc diagram - </i>by <a href="https://bl.ocks.org/rpgove/53bb49d6ed762139f33bdaea1f3a9e1c">Robert Gove</a></li>
          <br>
          <li><i>Arc diagram - </i>by <a href="http://bl.ocks.org/mayblue9/dcc49ef6e3888f37f755177c4a248f2c">MayBlue9</a></li>
        </ul>
      </div>
    </div>
  </div>
</section>

















<!-- ============================ CONTACT SECTION ============================ -->

  <!-- ANCHOR -->
  <a name="contactanchor"></a>


<section id="contact" class="bg" style="background-color: white"></section>

<!-- THIS ALLOWS TO INSERT THE CONTACT CHUNK THAT IS STORED IN A CONTACT.HTML FILE-->
<script>
$(function(){
  $("#contact").load("../html_chunk/contact.html");
});
</script>













<!-- ============================ FOOTER SECTION ============================ --><footer class="bg-light" id="myFooter"></footer>

<!-- THIS ALLOWS TO INSERT THE FOOTER THAT IS STORED IN A FOOTER.HTML FILE-->
<script>
$(function(){
  $("#myFooter").load("../html_chunk/footer.html");
});
</script>

<!-- ============================ -->




















<!-- ============================ JAVASCRIPT SECTION ============================ -->

<!-- Bootstrap core JavaScript -->
<script src="../vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

<!-- Custom scripts for this template -->
<script src="../js/agency.min.js"></script>

<!-- Activate the bootstrap tooltip, must be after jQuery load -->
<script>
  $(function () {
      $('[data-toggle="tooltip"]').tooltip()
  })
</script>



<script>
showCodeVersion('v4')
</script>







</body>

</html>
